//
//  ViewController.swift
//  FireBOOM
//
//  Created by ktiays on 2020/7/22.
//

import UIKit

// MARK: - Extension

extension String {
    var integer: Int? { Int(self) }
}

extension Double {
    var integer: Int { Int(self) }
}

extension Int {
    
    /// 使当前数值在某一范围内随机波动
    /// - Parameter range: 范围
    /// - Returns: 随机波动后的值
    func surge(_ range: Int) -> Int {
        self + Int(arc4random_uniform(UInt32(range * 2 + 1))) - range
    }
}

func + (_ lhs: Model, _ rhs: Step) -> Model {
    let tempModel = Model(lhs)
    tempModel.conc += rhs.deltaConc
    tempModel.temperature += rhs.deltaTemp
    return tempModel
}

// MARK: - View Controller

class ViewController: UIViewController {
    
    /// 设备状态
    @IBOutlet weak var deviceMimic: UISwitch!
    /// 用户ID
    @IBOutlet weak var userText: UITextField!
    
    /// 温度文本
    @IBOutlet weak var temperatureText: UITextField!
    /// 温度控制
    @IBOutlet weak var temperatureStepper: UIStepper!
    
    /// 浓度文本
    @IBOutlet weak var concText: UITextField!
    /// 浓度控制
    @IBOutlet weak var concStepper: UIStepper!
    
    /// 火焰状态
    @IBOutlet weak var fireState: UISwitch!
    
    private var timer: Timer = Timer()
    
    private var origin: Model!
    private var current: Model!
    private var target: Model!
    
    /// 浓度浮动范围
    private let concFluctuation: Int = 2
    /// 温度浮动范围
    private let tempFluctuation: Int = 2
    
    /// 浓度步长阈值绝对值
    private let concThreshold: Int = 3
    /// 温度步长阈值绝对值
    private let tempThreshold: Int = 2
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        deviceMimic.addTarget(self, action: #selector(deviceStateDidChange(_:)), for: .valueChanged)
        
        temperatureStepper.value = 28
        temperatureStepper.addTarget(self, action: #selector(tempDidChange(_:)), for: .valueChanged)
        
        concStepper.value = 10
        concStepper.addTarget(self, action: #selector(concDidChange(_:)), for: .valueChanged)
    }
    
    @objc func tempDidChange(_ sender: UIStepper) {
        self.temperatureText.text = sender.value.integer.description
        origin = current
    }
    
    @objc func concDidChange(_ sender: UIStepper) {
        self.concText.text = sender.value.integer.description
        origin = current
    }
    
    @objc func deviceStateDidChange(_ sender: UISwitch) {
        if sender.isOn {
            userText.isEnabled = false
            
            origin = currentStatus()
            current = Model(origin)
            
            timer = Timer.scheduledTimer(withTimeInterval: 1, repeats: true, block: { [self] (_) in
                current.send()
                target = currentStatus()
                // 最大步长
                let maxStep = Step(deltaConc: target.conc - current.conc, deltaTemp: target.temperature - current.temperature)
                // 标准步长
                var standConc = (target.conc - origin.conc) / 12
                var standTemp = (target.temperature - origin.temperature) / 12
                // 设置步长阈值
                standConc = abs(standConc) < concThreshold ? concThreshold * standConc.signum() : standConc
                standConc = abs(standConc) > abs(maxStep.deltaConc) || standConc.signum() != maxStep.deltaConc.signum() ? maxStep.deltaConc : standConc
                
                standTemp = abs(standTemp) < tempThreshold ? tempThreshold * standTemp.signum() : standTemp
                standTemp = abs(standTemp) > abs(maxStep.deltaTemp) || standTemp.signum() != maxStep.deltaTemp.signum() ? maxStep.deltaTemp : standTemp
                // 浓度与温度发生变化
                current = current + Step(deltaConc: standConc, deltaTemp: standTemp)
                // 火焰状态发生变化
                current.detected = target.detected
                // 模拟波动
                current.surge(concRange: concFluctuation, tempRange: tempFluctuation)
            })
        } else {
            userText.isEnabled = true
            timer.invalidate()
        }
    }
    
    /// 获取当前数据状态
    /// - Returns: 当前数据的 Model
    private func currentStatus() -> Model {
        Model(id: userText.text?.integer ?? 1, conc: self.concText.text?.integer ?? 10, temp: self.temperatureText.text?.integer ?? 28, detected: fireState.isOn)
    }
}
